﻿
#include <iostream>
#include "gtest\gtest.h"

#include "Common/smart_ptr.h"

class TestSmartPtr : public testing::Test {
protected:
    static void SetUpTestSuite()
    {
        std::cout << "run before first case..." << std::endl;
    }

    static void TearDownTestSuite()
    {
        std::cout << "run after last case..." << std::endl;
    }

    virtual void SetUp() override
    {
        std::cout << "enter into SetUp()" << std::endl;
    }

    virtual void TearDown() override
    {
        std::cout << "exit from TearDown" << std::endl;
    }
};

TEST_F(TestSmartPtr, test0)
{
    CodingSea::SmartPtr<int> p1;
    EXPECT_EQ(p1.Get(), nullptr);
    EXPECT_EQ(p1.GetRef(), 1);

    int* n1 = new int(5);

    // T*赋值运算符
    p1 = n1;

    // 拷贝构造函数
    CodingSea::SmartPtr<int> p2(p1);

    CodingSea::SmartPtr<int> p3;
    // SmartPtr赋值运算符
    p3 = p2;

    // 此时p1, p2, p3 ---> n1
    EXPECT_EQ(p3.Get(), n1);
    EXPECT_EQ(p3.GetRef(), 3);

    // *运算符
    EXPECT_EQ(*p3, *n1);

    // !运算符
    EXPECT_EQ(!p3, false);

    // unspecified_bool_type运算符
    bool isNull = true;
    if (p3) {
        isNull = false;
    }
    EXPECT_EQ(isNull, false);

    // ==运算符
    EXPECT_EQ(p1 == p3, true);
    
    // T*构造函数
    int* n2 = new int(6);
    CodingSea::SmartPtr<int> p4(n2);
    p3 = p4;
    p4 = nullptr;

    // 此时p1, p2 ---> n1, p3 ---> n2, p4 ---> nullptr
    EXPECT_EQ(p2.GetRef(), 2);
    EXPECT_EQ(*p2, *n1);

    EXPECT_EQ(p3.GetRef(), 1);
    EXPECT_EQ(*p3, *n2);

    EXPECT_EQ(p4, nullptr);
}
